﻿using System;
using System.Collections;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using GeneralLibs;
using Lists;

namespace KhuyenMai
{
    public class ChuongTrinhKhuyenMai : DoiTuong
    {
        #region Ma property
        public string Ma
        {
            get
            {
                return (string)_DataRow["Ma"];
            }
            set
            {
                _DataRow["Ma"] = value;
            }
        }
        #endregion

        #region DienGiai property
        public string DienGiai
        {
            get
            {
                return (string)_DataRow["DienGiai"];
            }
            set
            {
                _DataRow["DienGiai"] = value;
            }
        }
        #endregion

        #region NgayBatDau property
        public DateTime NgayBatDau
        {
            get
            {
                if (_DataRow["NgayBatDau"] is DateTime)
                {
                    return (DateTime)_DataRow["NgayBatDau"];
                }
                else return DateTime.MinValue;
            }
            set
            {
                _DataRow["NgayBatDau"] = value;
            }
        }
        #endregion

        #region NgayKetThuc property
        public DateTime NgayKetThuc
        {
            get
            {
                if (_DataRow["NgayKetThuc"] is DateTime)
                {
                    return (DateTime)_DataRow["NgayKetThuc"];
                }
                else return DateTime.MinValue;
            }
            set
            {
                _DataRow["NgayKetThuc"] = value;
            }
        }
        #endregion

        #region KieuKhuyenMai property
        private int _KieuKhuyenMai;
        public int KieuKhuyenMai
        {
            get
            {
                return (int)_DataRow["KieuKhuyenMai"];
            }
            set
            {
                _DataRow["KieuKhuyenMai"] = value;
            }
        }
        #endregion

        #region NgayTao property
        public DateTime NgayTao
        {
            get
            {
                if (_DataRow["NgayTao"] is DateTime)
                {
                    return (DateTime)_DataRow["NgayTao"];
                }
                else return DateTime.MinValue;
            }
            set
            {
                _DataRow["NgayTao"] = value;
            }
        }
        #endregion

        #region NgayBatDauTinhTongTien property
        public DateTime? NgayBatDauTinhTongTien
        {
            get
            {
                if (_DataRow["NgayBatDauTinhTongTien"] is DateTime)
                {
                    return (DateTime)_DataRow["NgayBatDauTinhTongTien"];
                }
                else return null;
            }
            set
            {
                if(value == null)_DataRow["NgayBatDauTinhTongTien"] = DBNull.Value;
                else _DataRow["NgayBatDauTinhTongTien"] = value;
            }
        }
        #endregion

        #region NgayKetThucTinhTongTien property
        public DateTime? NgayKetThucTinhTongTien
        {
            get
            {
                if (_DataRow["NgayKetThucTinhTongTien"] is DateTime)
                {
                    return (DateTime)_DataRow["NgayKetThucTinhTongTien"];
                }
                else return null;
            }
            set
            {
                if (value == null) _DataRow["NgayKetThucTinhTongTien"] = DBNull.Value;
                else _DataRow["NgayKetThucTinhTongTien"] = value;
            }
        }
        #endregion

        #region DanhSachChuongTrinhKhuyenMai property
        private DanhSachChuongTrinhKhuyenMai _DanhSachChuongTrinhKhuyenMai;
        public DanhSachChuongTrinhKhuyenMai DanhSachChuongTrinhKhuyenMai
        {
            get
            {
                return _DanhSachChuongTrinhKhuyenMai;
            }
            set
            {
                _DanhSachChuongTrinhKhuyenMai = value;
            }
        }
        #endregion

        public override void InsertToDB()
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand();
                InsertToDB(cmd);
            }
            catch (SqlException sqlEx)
            {
                throw new CustomException(GeneralLibs.CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
            finally
            {
                con.Close();
            }
        }
        public override void InsertToDB(SqlCommand cmd)
        {
            if (cmd.Connection.State != ConnectionState.Open) throw new CustomException("Chưa mở connection");
            string values = ""; string listOfColumns = "";
            cmd.Parameters.Clear();
            foreach (DataColumn column in this.DataRow.Table.Columns)
            {
                if (column.ColumnName != "LastUpdated")
                {
                    values = values + "@" + column.ColumnName + ", ";
                    listOfColumns = listOfColumns + column.ColumnName + ", ";
                    cmd.Parameters.AddWithValue(column.ColumnName, this.DataRow[column.ColumnName]);
                }
            }

            if (values.EndsWith(", ")) values = values.Substring(0, values.Length - 2);
            if (listOfColumns.EndsWith(", ")) listOfColumns = listOfColumns.Substring(0, listOfColumns.Length - 2);

            cmd.CommandText = string.Format("INSERT INTO {0}({1}) VALUES({2})",
                                                this.DataRow.Table.TableName, listOfColumns, values);
            cmd.ExecuteNonQuery();
            if (this.DataRow.Table.Rows.IndexOf(this.DataRow) < 0) this.DataRow.Table.Rows.Add(this.DataRow);

            #region Add ChuongTrinhKhuyenMai.DataRow to DanhSachChuongTrinhKhuyenMai.DataTable for auto refresh list
            _DanhSachChuongTrinhKhuyenMai = DanhSachChuongTrinhKhuyenMai.Instance;

            if (_DanhSachChuongTrinhKhuyenMai.DataTable.Rows.IndexOf(_DataRow) < 0)
            {
                _DanhSachChuongTrinhKhuyenMai.LoadFromDB((KieuKhuyenMai)(int)_DataRow["KieuKhuyenMai"]);
                //_DanhSachChuongTrinhKhuyenMai.DataTable.Rows.Add(_DataRow);
            }
            #endregion
        }

        public ChuongTrinhKhuyenMai(DataRow dataRow)
            : base(dataRow)
        {
            _DataRow = dataRow;
        }
    }

    public class DanhMucChuongTrinhKhuyenMai : DanhMucDoiTuong, IEnumerable
    {
        #region Instance property: Singleton Design pattern
        private static DanhMucChuongTrinhKhuyenMai _Instance;
        public static DanhMucChuongTrinhKhuyenMai Instance
        {
            get
            {
                if (_Instance == null)
                {
                    _Instance = new DanhMucChuongTrinhKhuyenMai();
                    _Instance.DataView = _Instance.DataTable.DefaultView;
                }
                return _Instance;
            }
        }
        #endregion

        #region override TableName property
        public override string TableName
        {
            get
            {
                return "ChuongTrinhKhuyenMai";
            }
        }
        #endregion

        #region Methods required by IEnumerable (use for foreach)
        public IEnumerator GetEnumerator()
        {
            return new TokenEnumerator(this);
        }

        private class TokenEnumerator : IEnumerator
        {
            private int _Position = -1;
            DanhMucDoiTuong _Dstk;

            public TokenEnumerator(DanhMucDoiTuong dstk)
            {
                _Dstk = dstk;
            }

            // Declare the MoveNext method required by IEnumerator:
            public bool MoveNext()
            {
                if (_Position < _Dstk.DataView.Count - 1)
                {
                    _Position++;
                    return true;
                }
                else
                {
                    return false;
                }
            }

            // Declare the Reset method required by IEnumerator:
            public void Reset()
            {
                _Position = -1;
            }

            // Declare the Current property required by IEnumerator:
            public object Current
            {
                get
                {
                    return new ChuongTrinhKhuyenMai((_Dstk.DataView[_Position].Row));
                }
            }
        }
        #endregion

        public ChuongTrinhKhuyenMai this[int index]
        {
            get
            {
                if (0 <= index && index <= this.Count)
                {
                    return new ChuongTrinhKhuyenMai(DataTable.Rows[index]);
                }
                else
                {
                    return null;
                }
            }
        }

        public ChuongTrinhKhuyenMai NewDoiTuong()
        {
            return new ChuongTrinhKhuyenMai(DataTable.NewRow());
        }

        public ChuongTrinhKhuyenMai GetByProperty(string property, object value)
        {
            try
            {
                DataRow[] rows = GetDataRows(property, value);
                if (rows.Length > 0) return new ChuongTrinhKhuyenMai(rows[0]);
                else return null;
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public ChuongTrinhKhuyenMai GetByID(Guid objID)
        {
            return GetByProperty("ID", objID);
        }

        public static DanhMucChuongTrinhKhuyenMai GetAll()
        {
            return Instance;
        }

        public static DanhMucChuongTrinhKhuyenMai Filter(string filterExpression)
        {
            try
            {
                DanhMucChuongTrinhKhuyenMai obj = new DanhMucChuongTrinhKhuyenMai();
                obj.DataView = new DataView(DanhMucChuongTrinhKhuyenMai.Instance.DataTable, filterExpression, "Ma", DataViewRowState.CurrentRows);
                return obj;
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public static ChuongTrinhKhuyenMai GetByMa(string ma)
        {
            try
            {
                return DanhMucChuongTrinhKhuyenMai.Instance.GetByProperty("Ma", ma);
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public void DeleteChuongTrinhKhuyenMaiByChuongTrinhKhuyenMaiIDFromDB(Guid chuongTrinhKhuyenMaiID)
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            try
            {
                con.Open();
                SqlCommand cmd = con.CreateCommand();
                DeleteChuongTrinhKhuyenMaiByChuongTrinhKhuyenMaiIDFromDB(cmd, chuongTrinhKhuyenMaiID);
                base.LoadFromDB();
            }
            catch (SqlException sqlEx)
            {
                throw new CustomException(GeneralLibs.CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
            finally
            {
                con.Close();
            }
        }
        public void DeleteChuongTrinhKhuyenMaiByChuongTrinhKhuyenMaiIDFromDB(SqlCommand cmd, Guid chuongTrinhKhuyenMaiID)
        {
            try
            {
                cmd.CommandText = string.Format("DELETE FROM ChuongTrinhKhuyenMai WHERE ID = '{0}'",
                                                    chuongTrinhKhuyenMaiID);
                cmd.ExecuteNonQuery();
                DataRow[] rows = DataTable.Select(string.Format("ID = '{0}'", chuongTrinhKhuyenMaiID));
                foreach (DataRow r in rows)
                {
                    DataTable.Rows.Remove(r);
                }
            }
            catch (SqlException sqlEx)
            {
                throw new CustomException(GeneralLibs.CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        public void DeleteAllRelatedFromDB(Guid chuongTrinhKhuyenMaiID, KieuKhuyenMai kieuKhuyenMai)
        {
            SqlConnection con = new SqlConnection(GeneralLibs.LocalSettings.ConnectString);
            SqlTransaction trans = null;
            try
            {
                con.Open();
                trans = con.BeginTransaction();
                SqlCommand cmd = con.CreateCommand();
                cmd.Transaction = trans;
                ChuongTrinhKhuyenMai chuongTrinhKhuyenMai = DanhMucChuongTrinhKhuyenMai.Instance.GetByID(chuongTrinhKhuyenMaiID);
                if (chuongTrinhKhuyenMai != null && chuongTrinhKhuyenMai.KieuKhuyenMai == (int)KieuKhuyenMai.TheoThoiGian)
                {
                    DanhMucChiTietKhuyenMaiTheoThoiGian.Instance.DeleteChiTietKhuyenMaiTheoThoiGianByChuongTrinhKhuyenMaiIDFromDB(cmd, chuongTrinhKhuyenMaiID);
                }
                else if (chuongTrinhKhuyenMai != null && chuongTrinhKhuyenMai.KieuKhuyenMai == (int)KieuKhuyenMai.TheoTongTienTichLuy)
                {
                    DanhMucChiTietKhuyenMaiTheoTongTienTichLuy.Instance.DeleteChiTietKhuyenMaiTheoTongTienTichLuyByChuongTrinhKhuyenMaiIDFromDB(cmd, chuongTrinhKhuyenMaiID);
                }
                DanhMucDoiTuongKhuyenMai.Instance.DeleteDoiTuongKhuyenMaiByChuongTrinhKhuyenMaiIDFromDB(cmd, chuongTrinhKhuyenMaiID);
                DanhMucChuongTrinhKhuyenMai.Instance.DeleteChuongTrinhKhuyenMaiByChuongTrinhKhuyenMaiIDFromDB(cmd, chuongTrinhKhuyenMaiID);
                trans.Commit();
            }
            catch (SqlException sqlEx)
            {
                trans.Rollback();
                throw new CustomException(GeneralLibs.CustomException.GetSqlExceptionMessage(sqlEx));
            }
            catch (Exception ex)
            {
                trans.Rollback();
                if (ex is CustomException) throw ex;
                else
                {
                    throw new Exception(ex.Message);
                }
            }
            finally
            {
                DanhSachChuongTrinhKhuyenMai.Instance.LoadFromDB(kieuKhuyenMai);
                con.Close();
            }
        }
    }
}
